git clone git@xxxxx # 或https://xxxx,把文件clone到本地。
git clone -b dev1 git@xxxx # clone repo的dev1分支
git init # 初始化git目录(最好空白文件夹的时候)。
git config --global XXXX # 修改一些全局变量
git config --global user.name "Zhang San"
git config --global user.email zhangsan@example.com
git remote 显示远程仓库信息
git remote -v
git remote set-url origin http://xx.xx.xx.xx:port/zhang/git_test.git
git config user.name
git config user.email # 查看用户名和邮箱地址
git status # 查看文件状态
git diff A.txt # 查看A文件有哪些改动
git diff --cached # 查看已经add过但还没commit的内容
git diff branch1 branch2 -- file.txt # 比较两个分支的同个文件
git diff --cached # 查看已add但没commit的数据
git difftool --dir-diff commit1 commit2 # 本地查看 diff,使用工具
git show # 查看最近的commit内容
git add A.txt # 提交A文件(add完以后最好stash或者commit,免得丢了)
git add -u # 只提交update文件
git add -p # 逐条选择是否add
git mv old_file.txt new_file.txt
git rm A.txt # 把本地和远程文件A都删了
git rm -cached A.txt # 远程删,本地不删
git clean -n 查看要删除那些多余文件
git clean -df 真的删除这些文件
git log # 查看文件修改log
git log -p # 查看指定文件的提交历史
git log --grep "test" # 查找包含test字段的提交
git log --author="John Doe" # 查找所有由"John Doe"撰写的提交记录
git log --author="john@example.com" # 查找"john@example.com"撰写的提交记录
git log --name-status # 每次修改的文件列表, 显示状态
git log --name-only # 每次修改的文件列表
git log --stat # 每次修改的文件列表, 及文件修改的统计
git log commit_id_A..commit_id_B --no-merges --author='^(?!John|Bob).*S' --perl-regexp --pretty=format:"%h %an %s"
# --no-merges 不显示merge的commit
# --perl-regexp 使用perl正则
# --pretty=format: format显示哪些内容
git blame # 查看列表形式的提交历史
git blame file_name
git blame -L 58,100 KeyboardActivity.java
git reflog # 查看本地所有分支的提交历史
git whatchanged # 每次修改的文件列表
git whatchanged --stat # 每次修改的文件列表, 及文件修改的统计
如果在当前分支做了修改,却需要保存但不提交的话,使用 stash。比如当前的修改想挪到其他分支;或者当前的修改还不能 commit,但是要去修改别的分支。stash 的内容包括已经 add 或还没 add 的内容,不包括已经 commit 的内容。
git stash # 暂存目前修改
git stash pop # 将暂存的最新内容pop出来
git stash -p # 交互式决定每个修改是否暂存
git commit # 提交本地修改:说明修改了啥
git commit -m # 一行描述提交commit
git commit --am # 在当前commit基础上追加
git commit --amend # 同上,修改提交,比如先add,再amend
commit description,以下为 type 类型
feat : 新功能
fix : 修复bug
docs : 文档改变
style : 代码格式改变
refactor : 某个已有功能重构
perf : 性能优化
test : 增加测试
build : 改变了build工具 如 grunt换成了 npm
revert : 撤销上一次的 commit
chore : 构建过程或辅助工具的变动
git reset --hard HEAD # 撤销工作目录中没提交的文件的修改内容
git reset --soft commit_id # 撤销操作,保留文件
git checkout HEAD <file> # 撤销指定的未提交文件的修改内容
git checkout -- filename # 撤销这个文件的修改
git revert <commit> # 撤销这个commit
git revert -m 1 start_commit_id^..end_commit_id # -m 用来处理有merge的分支
# 如果我们想把这三个revert不自动生成三个新的commit,而是用一个commit完成,可以这样:
git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"
# git rm的撤销
git rm (-r) file
git status # 查看
git reset -- file
git checkout -- ./file
git branch # 显示当前分支和所有分支
git branch -b new_branch # 新增分支 new_branch
git branch -m old_branch new_branch # 重命名本地分支,从旧的old_branch更新为新的new_branch
git branch -a # 列举本地和远程的所有branch
git checkout -b new_branch # 从当前分支新增且切换到分支dev1
git merge B # 在分支A上,合并分支B,形成新的commit,对B分支没有影响。
git fetch # 更新远程分支上最新的commit,记录到.git/FETCH_HEAD
git pull # 更新分支,相当于fetch+merge
git pull origin master # 下拉 master 分支的代码,合并到当前分支
git pull --rebase origin master # 下拉合并master并且不增加commit
git checkout -b A origin/B # 以远程分支B为来源,在本地仓库中创建分支A
git push origin remote_branch # 将代码推到 remote_branch 分支
git push origin local_branch:master # 将代码从 local_branch 分支推到 master
git branch -D branch_1 # 删除本地分支 branch_1
git push origin --delete remote_branch # 删除远程分支 remote_branch
# 以图表形式查看分支,图上每个点表示一个commit,两个commit之间如果有线连接,那么下面的commit是上面一个commit的parent(父节点)。
git log --graph
git branch -r # 查看所有远程分支名
git diff local_branch remote_branch
冲突解决:冲突形如:<<<<<<< HEAD,=======,>>>>>>>
选择需要保留的 code 并提交。
rebase:rebase 我觉得是用来缝合的功能。比如 N 个 commit,对其进行排序、修改,对某个历史 commit 的内容修改。
git rebase --abort # 放弃合并,回到rebase操作之前的状态,之前的提交的不会丢弃;
git rebase --skip # 将引起冲突的commits丢掉(慎用);
git rebase --continue # 合并冲突,分步进行
git ls-remote <remote_name> # 按名称查询远程分支
git ls-remote <remote_name> | grep <branch_name>
#### 去掉中间某次 commit
1. 首先 `git log` 查看提交记录,找到出错的前一笔提交的 commit_id
2. 用命令 `git rebase -i commit_id` ,查找提交记录
3. 将出错那笔提交的 pick 改为 drop
```bash
git log
git rebase -i commit_id
# set drop
git reset # 撤销
git reset --soft commit_id # 撤销到commit_id的对应提交,并且保留吃从commit_id到最近的更改。如果commit已经提交过,需要push --force才能重新推到远端
git reset --hard commit_id # 撤销到commit_id的对应提交,强制,所有之后的改动都会消失。如果commit已经提交过,需要push --force才能重新推到远端
git revert commit_id # 撤销commit_id对应的提交,并且push时会留下commit_id和对应revert动作的commit记录,也就是所有的行为都会有迹可循。
git revert commit_revert # 假如提交了commit_1,并且revert commit_1生成了commit_revert,撤销 commit_revert
git checkout HEAD # 撤销到HEAD指针处
git checkout ./some_file # 撤销对某个文件的未提交修改
git commit --amend # 将修改的代码追加到当前的最近一个commit
# 撤销 --amend
如果只 amend 了一次, 那么直接 git reset HEAD@{1} 就可以撤销这次 amend.
如果 amend 多次, 就参考 git reflog 进行撤销. 找到需要保留的,然后重新pull。
git rebase -i # 在其中调整 commit 的顺序、删除不想要的提交、以及合并提交
git rebase -i HEAD~4 # 调整HEAD最近的4次commit
cherry-pick,就是把需要的某些个 commit pick 到另一个分支。
git cherry-pick commit_id # commit_id原本属于其他分支,cherry-pick将commit_id 从其他的分支复制到当前的分支的 HEAD 上
git cherry-pick commit_1 commit2 # cherry-pick多个commit,这些commit可以在时间和分支上都不相关,生成两个新的commit
git cherry-pick commit_old^..commit_new # 选择从commit_1到commit_2的所有commit,是闭区间[commit_1, commit_2]
git cherry-pick commit_old..commit_new # (commit_1, commit_1] 左开右闭
git cherry-pick -X ignore-all-space commit-id # 提交时不提交那些只有换行符不同的行
git checkout A # 先切换到A分支
git cherry-pick commit_id_from_branchB # 将B分支上的commit挑过来
cherry-pick 和 rebase 一样,通过 abort、continue 决定每个分支的去留
git file mode change
是指用户权限变了,比如 100644-100755 之类的。
不提交这个的方法:
git config core.filemode false` `git config --global core.filemode false
在分支 A 上修改文件但是没有提交(commit),切换到分支 B,B 也能看到,状态为 M。
在分支 A 上修改文件,提交了,切换到分支 B,B 看不到。
git stash # 将本地修改的代码放到栈里
git stash pop # 将提交到栈里的代码 pop 出来
git reset HEAD # 恢复文件到 HEAD(如果误 add 了一个 A 文件,可以使用)
git reset A.txt # (恢复一个文件 A)
git diff --stat
git diff SHA1 SHA2
git diff HEAD^ HEAD
git reflog
首先使用 git reflog 命令查看操作记录:
$ git reflog
c1c1b21 HEAD@{0}: commit (amend): add blank line to index.html
9ff821d HEAD@{1}: commit: add blank line to index.html
b078331 HEAD@{2}: commit: no more commit!
b86e902 HEAD@{3}: commit: so many commit
77e6ce9 HEAD@{4}: commit: this is another commit
ccde039 HEAD@{5}: commit: this is a commit
a49dcf4 HEAD@{6}: clone: from ssh://liux@xxx.xx.xx.xxx:29418/git_test.git
看到 amend 操作之前的最后一个操作就是 HEAD@{1}.
现在可以用 git reset 将当前分支的 HEAD 指向 HEAD@{1}, 即可达到撤销 amend 的目的:
$ git reset --soft HEAD@{1}
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
随即使用 git status 查看状态, 发现 amend 的内容已经被撤销 (到工作区) 了.
如果想撤销到暂存区, 就用 git reset --soft HEAD@{1} .
如果想干掉这个修改, 就用 git reset --hard HEAD@{1} .
这和 git reset 操作 commit 的情形是一样的.
如果一个 commit 被 amend 了多次, 也可以用这种方法撤销到任意一次 amend 处:
问题背景
笔者最近在实习发现了这么一个问题,push 了一个提交但是这个提交中误删了两个文件,现在需要撤销错误的删除并重新提交
解决过程
首先查询这个文件的 log git log <fileName>
其次查找到这个文件的上次 commit id xxx,并对其进行 reset 操作 git reset <commit-id> <fileName>
再撤销对此文件的修改 git checkout <fileName>
最后 amend 一下,再 push 上去
git commit --amend
git push origin <remoteBranch>
git checkout -b w3h5 af161ecbd13eff1630c14f84a7395d46f5d18888
查看提交历史,git log
假如,想要合并前三条,git rebase -i HEAD~3
,将 pick 改为 squash 或者 s,之后保存并关闭文本编辑窗口即可
重新提交
git add .
git rebase --continue
或者 git reset --soft commit-id
,git commit --amend,然后重新提交。